//
//  File.swift
//  
//
//  Created by Test User on 6/1/20.
//

import Fluent
import Vapor

//final class User: Model, Content {
final class User: Model {
      struct Public: Content {
        let username: String
        let id: UUID
        let createdAt: Date?
        let updatedAt: Date?
      }
      
      static let schema = "user"
      
      @ID(key: "id")
      var id: UUID?
      
      @Field(key: "username")
      var username: String
      
      @Field(key: "password_hash")
      var passwordHash: String
      
      @Timestamp(key: "created_at", on: .create)
      var createdAt: Date?
      
      @Timestamp(key: "updated_at", on: .update)
      var updatedAt: Date?
      
      init() {}
      
      init(id: UUID? = nil, username: String, passwordHash: String) {
        self.id = id
        self.username = username
        self.passwordHash = passwordHash
      }
    }

    extension User {
      static func create(from userSignup: UserSignup) throws -> User {
        User(username: userSignup.username, passwordHash: try Bcrypt.hash(userSignup.password))
      }
      
      func createToken(source: SessionSource) throws -> Token {
        let calendar = Calendar(identifier: .gregorian)
        let expiryDate = calendar.date(byAdding: .year, value: 1, to: Date())
        return try Token(userId: requireID(),
          token: [UInt8].random(count: 16).base64, source: source, expiresAt: expiryDate)
      }
//        func deleteToken(source: SessionSource) throws -> Response {
//          let calendar = Calendar(identifier: .gregorian)
//          let expiryDate = calendar.date(byAdding: .year, value: 1, to: Date())
//          return try Token(userId: requireID(),
//            token: [UInt8].random(count: 16).base64, source: source, expiresAt: expiryDate)
//
//            
//        }

      func asPublic() throws -> Public {
        Public(username: username,
               id: try requireID(),
               createdAt: createdAt,
               updatedAt: updatedAt)
      }
    }

    extension User: ModelAuthenticatable {
      static let usernameKey = \User.$username
      static let passwordHashKey = \User.$passwordHash
      
      func verify(password: String) throws -> Bool {
        try Bcrypt.verify(password, created: self.passwordHash)
      }
    }
